package com.liuweiheng.cloudpayment8003.redisson;

import cn.hutool.core.util.StrUtil;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 基础控制器
 * 测试分布式锁扣减库存
 *
 * @author lwh
 */
@RestController
@RequestMapping("/redis/index")
public class IndexController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 产品库存分布式锁名称
     */
    private String lockKey = "product_001";

    private String clientId = UUID.randomUUID().toString().trim();

    @Autowired
    private RedissonClient redissonClient;

    @RequestMapping("/reduceStock")
    public String reduceStock() {

        // 获取分布式锁对象
        RLock redissonLock = redissonClient.getLock(lockKey);

        //------------------------------------获取分布式锁

        /*
         获取分布式锁，并设置过期时间，防止服务宕机导致死锁(锁一直存在于redis中)
         会引起锁失效问题，假如业务逻辑花费时间较长，redis将锁删掉，其他线程就可以进来
         */
        try {

            /// setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS)
            /// redissonLock.lock(30, TimeUnit.SECONDS);
            redissonLock.lock();
            /*
            Boolean getLock = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, clientId, 10, TimeUnit.SECONDS);

            if (!getLock) {
                return "error_code";
            }
            */

            //------------------------------------ 创建子线程、执行定时任务，给锁续命(未完成)

            //------------------------------------ 执行业务逻辑
            // 获取库存
            String stockStr = stringRedisTemplate.opsForValue().get("stock");

            // 检查库存
            if(StrUtil.isBlank(stockStr)) {
                return "";
            }

            int stock = Integer.parseInt(stockStr);

            // 尝试扣减库存
            if (stock > 0) {
                int realStock = stock - 1;
                stringRedisTemplate.opsForValue().set("stock", realStock + "");
                System.out.println("扣减库存成功, 剩余库存：" + realStock);
            } else {
                System.out.println("扣减库存失败，库存不足");
            }

        } finally {
            //------------------------------------ 释放分布式锁

            redissonLock.unlock();


            // 判断锁是否是当前线程加的
            /*
            if (clientId.equals(stringRedisTemplate.opsForValue().get(lockKey))) {
                stringRedisTemplate.delete(lockKey);
            }
            */
        }



        return "end";
    }

}
